package com.elcom.roaming.module.synthesis.lb.client;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.BlockingQueue;

import org.slf4j.Logger;

import com.elcom.roaming.common.StringCouple;

public class LBClient extends ClientService implements Runnable{
	private static final int SEQ_QUOTA = 5000000;
	
	private BlockingQueue<StringCouple> queue;
	private String queueName;
	private int index;
	private Logger logger; 
	private boolean stop;
	
	public LBClient(Logger logger, int index, String host, int port, BlockingQueue<StringCouple> queue) {
		super(host, port);
		this.logger = logger;
		this.index = index;
		this.stop = false;
		this.queue = queue;
	}

	private void tryConnect(){
		boolean success = false;
		
		do {
			logger.info("Try connecting to LB server " + host + ":" + port + "...");
			success = connect();
			if (!success){
				logger.info("Connect fail to LB server " + host + ":" + port + ". Retry later...");
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					logger.error("Sleep error.", e);
				}
			}

		} while (!success);
		
		logger.info("Connect success to LB server " + host + ":" + port + "...");
	}
	
	@Override
	public void run() {
		tryConnect();
		
		int seq = (SEQ_QUOTA * index) + 1;
		
		while (!stop) {
			if (queue.isEmpty()) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					logger.error("Sleep error.", e);
				}
			}
			
			StringCouple couple = queue.poll();
			if (couple != null) {
				IPCFwc msg = new IPCFwc();
				msg.setSequenceNumber(seq++);
				if (seq >= SEQ_QUOTA * (1+index)) 
					seq = (SEQ_QUOTA * index) + 1;
				msg.setCalling(couple.getNumber1());
				msg.setCalled(couple.getNumber2());
				msg.setTime(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")
				.format(new Date()));
				msg.setLocation("Ha Noi, Viet Nam");
				
				int writeByte = -1;
				do  {
					writeByte = write(msg.getDataAsBytes());
				} while (writeByte == -1);
			}
		}
	}

	@Override
	protected void onError(int code, Throwable thw) {
		switch (code) {
		case ClientService.UNKOWN_HOST: 
			logger.error("Unkown host.");
			break;
		case ClientService.IO_CONNECT_FAIL:
			logger.error("I/O error occurs when creating the socket.");
			break;
		case ClientService.IO_WRITE_FAIL:
			logger.error("Socket write error.");
			if (! isConnected()){
				logger.error("Lost connection. Retry connecting.");
				tryConnect();
			}
		default:
			logger.error("Unknow error.");
			break;
		} 
	}

	@Override
	protected byte[] toByteArray(Object obj) {
		// TODO Auto-generated method stub
		return null;
	}

}
